package put.cs.two.to.tsp.models;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class NodeSet implements Cloneable {
    Set<Point> points = new HashSet<Point>();

    Set<Point> unused = new HashSet<Point>();

    private boolean filtered = false;

    public void add(Point point) {
        points.add(point);
        unused.add(point);
    }

    public static int getDistance(Point from, Point to) {
        double dx = from.getX() - to.getX();
        double dy = from.getY() - to.getY();
        return (int) (Math.sqrt(dx * dx + dy * dy) + 0.5);
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        NodeSet cloned = new NodeSet();
        cloned.points = new HashSet<Point>(points);
        cloned.unused = new HashSet<Point>(unused);
        return cloned;
    }

    public Point get(int startingIndex) {
        for (Point point : points) {
            if (point.getIndex() == startingIndex) {
                return point;
            }
        }
        return null;
    }

    public Point getMassCenter() {
        int count = points.size();
        int x = 0;
        int y = 0;

        for (Point p : points) {
            x += p.getX();
            y += p.getY();
        }
        x /= count;
        y /= count;

        Point point = new Point(x, y);
        return point;
    }

    public void setUsed(Point startingPoint) {
        for (Point point : points) {
            if (point.equals(startingPoint)) {
                unused.remove(point);
                return;
            }
        }
    }

    public Set<Point> getUnusedPoints() {
        return Collections.unmodifiableSet(unused);
    }

    public int getDestinatedCycleLength() {
        int destinatedCycleLenght = filtered ? points.size() : points.size() / 2;
        return destinatedCycleLenght;
    }

    public int getSize() {
        return points.size();
    }

    public void setFiltered(boolean isFiltered) {
        filtered = isFiltered;
    }
}
